package com.magenta.maxoptra.gis;

import java.io.Serializable;

import static com.magenta.maxoptra.gis.GisConstants.MAX_LATITUDE_ACCURACY;
import static com.magenta.maxoptra.gis.GisConstants.MAX_LONGITUDE_ACCURACY;

/**
 * Created by IntelliJ IDEA.
 * User: plotnikovv
 * Date: 24.12.2009
 * Time: 15:20:08
 */

/**
 * Join of latitude and longitude with their accuracy.
 */
public class RoutingCoordinate implements Serializable, GeographicCoordinates {
    String name;
    double latitude;
    double longitude;
    int latitudeInteger;
    int longitudeInteger;

    public int getLatitudeInteger() {
        return latitudeInteger;
    }

    public int getLongitudeInteger() {
        return longitudeInteger;
    }

    short latitudeAccuracy;
    short longitudeAccuracy;

    public RoutingCoordinate(String name, double latitude, double longitude, short latitudeAccuracy, short longitudeAccuracy) {
        this.name = name;
        this.latitudeAccuracy = latitudeAccuracy;
        this.longitudeAccuracy = longitudeAccuracy;
        double latSignFACTOR = Math.pow(10.0, latitudeAccuracy);
        double lonSignFACTOR = Math.pow(10.0, longitudeAccuracy);
        this.latitude = Math.round(latitude * latSignFACTOR) /latSignFACTOR;
        this.longitude = Math.round(longitude * lonSignFACTOR) /lonSignFACTOR;
        latitudeInteger = getIntCoord(latitude);
        longitudeInteger = getIntCoord(longitude);
    }

    public static int getIntCoord(double latitude) {
        return (int)Math.ceil(latitude * GisConstants.PRECISION_RATE);
    }

    public RoutingCoordinate(String name, double latitude, double longitude) {
        this(name, latitude, longitude, (short) MAX_LATITUDE_ACCURACY, (short) MAX_LONGITUDE_ACCURACY);
    }

    public RoutingCoordinate(double latitude, double longitude) {
        this(null, latitude, longitude);
    }

    public RoutingCoordinate(int lat, int lon) {
        latitudeInteger = lat;
        longitudeInteger = lon;
        latitude = latitudeInteger / (double)GisConstants.PRECISION_RATE;
        longitude = longitudeInteger / (double)GisConstants.PRECISION_RATE;
    }

    public String getName() {
        return name;
    }

    public double getLatitude() {
        return latitude;
    }

    public double getLongitude() {
        return longitude;
    }

    public float getLatitudeFloat() {
        return (float)latitude;
    }

    public float getLongitudeFloat() {
        return (float)longitude;
    }

    public short getLatitudeAccuracy() {
        return latitudeAccuracy;
    }

    public short getLongitudeAccuracy() {
        return longitudeAccuracy;
    }

    public GeographicCoordinates getGeoCoordinate() {
        return new GeographicCoordinates() {
            @Override
            public double getLatitude() {
                return latitude;
            }

            @Override
            public double getLongitude() {
                return longitude;
            }

            @Override
            public int getLatitudeInteger() {
                return latitudeInteger;
            }

            @Override
            public int getLongitudeInteger() {
                return longitudeInteger;
            }
        };
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof RoutingCoordinate)) return false;

        RoutingCoordinate that = (RoutingCoordinate) o;

        if (Double.compare(that.latitude, latitude) != 0) return false;
        if (Double.compare(that.longitude, longitude) != 0) return false;

        return true;
    }

    @Override
    public int hashCode() {
        int result;
        long temp;
        temp = latitude != +0.0d ? Double.doubleToLongBits(latitude) : 0L;
        result = (int) (temp ^ (temp >>> 32));
        temp = longitude != +0.0d ? Double.doubleToLongBits(longitude) : 0L;
        result = 31 * result + (int) (temp ^ (temp >>> 32));
        return result;
    }

    //    @Override
//    public boolean equals(Object obj) {
//        if (obj instanceof RoutingCoordinate) {
//            RoutingCoordinate to = (RoutingCoordinate) obj;
//            if (latitude == to.latitude && longitude == to.longitude) return true;
//        }
//        return false;
//    }


}
